home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 / Programming Windows 95.iso / code / CHAP04 / JUSTIFY1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  8.5 KB  |  239 lines

  1. /*-----------------------------------------
  2.    JUSTIFY1.C -- Justified Type Program
  3.                  (c) Charles Petzold, 1996
  4.   -----------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include "ezfont.h"
  8.  
  9. #define LEFT         0
  10. #define RIGHT        1
  11. #define CENTER       2
  12. #define JUSTIFIED    3
  13.  
  14. #define ALIGN        JUSTIFIED
  15.  
  16. #define MyCreateFont EzCreateFont (hdc, "Times New Roman", 150, 0, 0, TRUE)
  17.  
  18. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  19.  
  20. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  21.                     PSTR szCmdLine, int iCmdShow)
  22.      {
  23.      static     char szAppName[] = "Justify1" ;
  24.      HWND       hwnd ;
  25.      MSG        msg ;
  26.      WNDCLASSEX wndclass ;
  27.  
  28.      wndclass.cbSize        = sizeof (wndclass) ;
  29.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  30.      wndclass.lpfnWndProc   = WndProc ;
  31.      wndclass.cbClsExtra    = 0 ;
  32.      wndclass.cbWndExtra    = 0 ;
  33.      wndclass.hInstance     = hInstance ;
  34.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  35.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  36.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  37.      wndclass.lpszMenuName  = szAppName ;
  38.      wndclass.lpszClassName = szAppName ;
  39.      wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;
  40.  
  41.      RegisterClassEx (&wndclass) ;
  42.  
  43.      hwnd = CreateWindow (szAppName, "Justified Type",
  44.                           WS_OVERLAPPEDWINDOW,
  45.                           CW_USEDEFAULT, CW_USEDEFAULT,
  46.                           CW_USEDEFAULT, CW_USEDEFAULT,
  47.                           NULL, NULL, hInstance, NULL) ;
  48.  
  49.      ShowWindow (hwnd, iCmdShow) ;
  50.      UpdateWindow (hwnd) ;
  51.  
  52.      while (GetMessage (&msg, NULL, 0, 0))
  53.           {
  54.           TranslateMessage (&msg) ;
  55.           DispatchMessage (&msg) ;
  56.           }
  57.      return msg.wParam ;
  58.      }
  59.  
  60. void DrawRuler (HDC hdc, RECT *prc)
  61.      {
  62.      static int iRuleSize [16] = { 360, 72, 144, 72, 216, 72, 144, 72,
  63.                                    288, 72, 144, 72, 216, 72, 144, 72 } ;
  64.      int        i, j ;
  65.      POINT      ptClient ;
  66.  
  67.      SaveDC (hdc) ;
  68.                     // Set Logical Twips mapping mode
  69.  
  70.      SetMapMode (hdc, MM_ANISOTROPIC) ;
  71.      SetWindowExtEx (hdc, 1440, 1440, NULL) ;
  72.      SetViewportExtEx (hdc, GetDeviceCaps (hdc, LOGPIXELSX),
  73.                             GetDeviceCaps (hdc, LOGPIXELSY), NULL) ;
  74.  
  75.                     // Move the origin to a half inch from upper left
  76.  
  77.      SetWindowOrgEx (hdc, -720, -720, NULL) ;
  78.  
  79.                     // Find the right margin (quarter inch from right)
  80.  
  81.      ptClient.x = prc->right ;
  82.      ptClient.y = prc->bottom ;
  83.      DPtoLP (hdc, &ptClient, 1) ;
  84.      ptClient.x -= 360 ;
  85.  
  86.                     // Draw the rulers
  87.  
  88.      MoveToEx (hdc, 0,          -360, NULL) ;
  89.      LineTo   (hdc, ptClient.x, -360) ;
  90.      MoveToEx (hdc, -360,          0, NULL) ;
  91.      LineTo   (hdc, -360, ptClient.y) ;
  92.  
  93.      for (i = 0, j = 0 ; i <= ptClient.x ; i += 1440 / 16, j++)
  94.           {
  95.           MoveToEx (hdc, i, -360, NULL) ;
  96.           LineTo   (hdc, i, -360 - iRuleSize [j % 16]) ;
  97.           }
  98.  
  99.      for (i = 0, j = 0 ; i <= ptClient.y ; i += 1440 / 16, j++)
  100.           {
  101.           MoveToEx (hdc, -360, i, NULL) ;
  102.           LineTo   (hdc, -360 - iRuleSize [j % 16], i) ;
  103.           }
  104.  
  105.      RestoreDC (hdc, -1) ;
  106.      }
  107.  
  108. void Justify (HDC hdc, PSTR pText, RECT *prc, int iAlign)
  109.      {
  110.      int  xStart, yStart, iBreakCount ;
  111.      PSTR pBegin, pEnd ;
  112.      SIZE size ;
  113.  
  114.      yStart = prc->top ;
  115.      do                            // for each text line
  116.           {
  117.           iBreakCount = 0 ;
  118.           while (*pText == ' ')    // skip over leading blanks
  119.                pText++ ;
  120.           pBegin = pText ;
  121.  
  122.           do                       // until the line is known
  123.                {
  124.                pEnd = pText ;
  125.  
  126.                while (*pText != '\0' && *pText++ != ' ') ;
  127.                if (*pText == '\0')
  128.                     break ;
  129.                                    // for each space, calculate extents
  130.                iBreakCount++ ;
  131.                SetTextJustification (hdc, 0, 0) ;
  132.                GetTextExtentPoint32 (hdc, pBegin, pText - pBegin - 1, &size) ;
  133.                }
  134.           while ((int) size.cx < (prc->right - prc->left)) ;
  135.  
  136.           iBreakCount-- ;
  137.           while (*(pEnd - 1) == ' ')   // eliminate trailing blanks
  138.                {
  139.                pEnd-- ;
  140.                iBreakCount-- ;
  141.                }
  142.  
  143.           if (*pText == '\0' || iBreakCount <= 0)
  144.                pEnd = pText ;
  145.  
  146.           SetTextJustification (hdc, 0, 0) ;
  147.           GetTextExtentPoint32 (hdc, pBegin, pEnd - pBegin, &size) ;
  148.  
  149.  
  150.           switch (iAlign)               // use alignment for xStart
  151.                {
  152.                case LEFT:
  153.                     xStart = prc->left ;
  154.                     break ;
  155.  
  156.                case RIGHT:
  157.                     xStart = prc->right - size.cx ;
  158.                     break ;
  159.  
  160.                case CENTER:
  161.                     xStart = (prc->right + prc->left - size.cx) / 2 ;
  162.                     break ;
  163.  
  164.                case JUSTIFIED:
  165.                     if (*pText != '\0' && iBreakCount > 0)
  166.                          SetTextJustification (hdc,
  167.                               prc->right - prc->left - size.cx,
  168.                               iBreakCount) ;
  169.                     xStart = prc->left ;
  170.                     break ;
  171.                }
  172.  
  173.           TextOut (hdc, xStart, yStart, pBegin, pEnd - pBegin) ;
  174.           yStart += size.cy ;
  175.           pText = pEnd ;
  176.           }
  177.      while (*pText && yStart < prc->bottom) ;
  178.  
  179.      }
  180.  
  181. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  182.      {
  183.      static char szText[] = "Call me Ishmael. Some years ago -- never mind "
  184.                             "how long precisely -- having little or no money "
  185.                             "in my purse, and nothing particular to interest "
  186.                             "me on shore, I thought I would sail about a "
  187.                             "little and see the watery part of the world. It "
  188.                             "is a way I have of driving off the spleen, and "
  189.                             "regulating the circulation.  Whenever I find "
  190.                             "myself growing grim about the mouth; whenever "
  191.                             "it is a damp, drizzly November in my soul; "
  192.                             "whenever I find myself involuntarily pausing "
  193.                             "before coffin warehouses, and bringing up the "
  194.                             "rear of every funeral I meet; and especially "
  195.                             "whenever my hypos get such an upper hand of me, "
  196.                             "that it requires a strong moral principle to "
  197.                             "prevent me from deliberately stepping into the "
  198.                             "street, and methodically knocking people's hats "
  199.                             "off -- then, I account it high time to get to sea "
  200.                             "as soon as I can. This is my substitute for "
  201.                             "pistol and ball.  With a philosophical flourish "
  202.                             "Cato throws himself upon his sword; I quietly "
  203.                             "take to the ship. There is nothing surprising "
  204.                             "in this. If they but knew it, almost all men in "
  205.                             "their degree, some time or other, cherish very "
  206.                             "nearly the same feelings towards the ocean with "
  207.                             "me." ;
  208.  
  209.      HDC         hdc ;
  210.      PAINTSTRUCT ps ;
  211.      RECT        rcClient ;
  212.  
  213.      switch (iMsg)
  214.           {
  215.           case WM_PAINT:
  216.                hdc = BeginPaint (hwnd, &ps) ;
  217.  
  218.                GetClientRect (hwnd, &rcClient) ;
  219.                DrawRuler (hdc, &rcClient) ;
  220.  
  221.                rcClient.left  += GetDeviceCaps (hdc, LOGPIXELSX) / 2 ;
  222.                rcClient.top   += GetDeviceCaps (hdc, LOGPIXELSY) / 2 ;
  223.                rcClient.right -= GetDeviceCaps (hdc, LOGPIXELSX) / 4 ;
  224.  
  225.                SelectObject (hdc, MyCreateFont) ;
  226.  
  227.                Justify (hdc, szText, &rcClient, ALIGN) ;
  228.  
  229.                DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT)));
  230.                EndPaint (hwnd, &ps) ;
  231.                return 0 ;
  232.  
  233.           case WM_DESTROY:
  234.                PostQuitMessage (0) ;
  235.                return 0 ;
  236.           }
  237.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  238.      }
  239.